home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgramD2.iso
/
Borland
/
Borland C++ V5.02
/
INPROC.PAK
/
ENUMVAR.CPP
next >
Wrap
C/C++ Source or Header
|
1997-05-06
|
5KB
|
204 lines
// enumvar.cpp : implementation file
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "inproc.h"
#include "enumvar.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEnumVariant
IMPLEMENT_DYNCREATE(CEnumVariant, CCmdTarget)
CEnumVariant::CEnumVariant()
{
m_nIndex = 0;
m_nCount = 0;
m_pContents = NULL;
m_pClonedFrom = NULL;
// To keep the application running as long as an OLE automation
// object is active, the constructor calls AfxOleLockApp.
AfxOleLockApp();
}
CEnumVariant::~CEnumVariant()
{
if (m_pClonedFrom != NULL)
{
m_pClonedFrom->ExternalRelease();
}
else
{
for (int i = 0; i < m_nCount; ++i)
VariantClear(&m_pContents[i]);
delete[] m_pContents;
}
// To terminate the application when all objects created with
// with OLE automation, the destructor calls AfxOleUnlockApp.
AfxOleUnlockApp();
}
void CEnumVariant::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. This implementation deletes the
// object. Add additional cleanup required for your object before
// deleting it from memory.
delete this;
}
void CEnumVariant::SetContents(VARIANT* pContents, int nCount, int nIndex)
{
ASSERT(nIndex < nCount);
ASSERT(nCount == 0 || pContents != NULL);
ASSERT(pContents == NULL ||
AfxIsValidAddress(pContents, sizeof(VARIANT)*nCount, FALSE));
m_nCount = nCount;
m_pContents = pContents;
m_nIndex = nIndex;
}
BEGIN_MESSAGE_MAP(CEnumVariant, CCmdTarget)
//{{AFX_MSG_MAP(CEnumVariant)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEnumVariant interfaces
static void CopyVariantArray(VARIANT* pDest, VARIANT* pSrc, int nCount)
{
for (int i = 0; i < nCount; ++i)
VariantInit(&pDest[i]);
for (i = 0; i < nCount; ++i)
{
SCODE sc = GetScode(VariantCopy(&pDest[i], &pSrc[i]));
if (sc != NOERROR)
{
while (--i >= 0)
VariantClear(&pDest[i]);
AfxThrowMemoryException();
}
}
}
BEGIN_INTERFACE_MAP(CEnumVariant, CCmdTarget)
INTERFACE_PART(CEnumVariant, IID_IEnumVARIANT, EnumVARIANT)
END_INTERFACE_MAP()
STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::AddRef()
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::Release()
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
return pThis->ExternalRelease();
}
STDMETHODIMP CEnumVariant::XEnumVARIANT::QueryInterface(REFIID iid, void** ppvObj)
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj) ;
}
STDMETHODIMP CEnumVariant::XEnumVARIANT::Next(ULONG celt, VARIANT* rgvar, ULONG* pceltFetched)
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
ASSERT(celt > 0);
ASSERT(celt == 1 || pceltFetched != NULL);
if (pceltFetched != NULL)
*pceltFetched = 0;
int nFetched = min(pThis->m_nCount - pThis->m_nIndex, (int)celt);
TRY
{
CopyVariantArray(rgvar, pThis->m_pContents + pThis->m_nIndex, nFetched);
}
CATCH_ALL(e)
{
return E_OUTOFMEMORY;
}
END_CATCH_ALL
pThis->m_nIndex += nFetched;
if (pceltFetched != NULL)
*pceltFetched = nFetched;
return nFetched == (int)celt ? NOERROR : S_FALSE;
}
STDMETHODIMP CEnumVariant::XEnumVARIANT::Skip(unsigned long celt)
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
int nSkip = (int)celt;
if (nSkip + pThis->m_nIndex > pThis->m_nCount)
nSkip = pThis->m_nCount - pThis->m_nIndex;
pThis->m_nIndex += nSkip;
return nSkip == (int)celt ? NOERROR : S_FALSE;
}
STDMETHODIMP CEnumVariant::XEnumVARIANT::Reset()
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
pThis->m_nIndex = 0;
return NOERROR;
}
STDMETHODIMP CEnumVariant::XEnumVARIANT::Clone(IEnumVARIANT** ppenum)
{
METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
CEnumVariant* pClone;
TRY
{
pClone = new CEnumVariant;
pClone->SetContents(pThis->m_pContents, pThis->m_nCount, pThis->m_nIndex);
pClone->m_pClonedFrom = pThis;
pThis->ExternalAddRef();
}
CATCH_ALL(e)
{
return E_OUTOFMEMORY;
}
END_CATCH_ALL
*ppenum = &pClone->m_xEnumVARIANT;
return NOERROR;
}
/////////////////////////////////////////////////////////////////////////////
// CEnumVariant message handlers